package pri.damai.xiaowu.gateway.security.config;

import pri.damai.xiaowu.common.security.config.XiaoWuSecurityProperties;
import pri.damai.xiaowu.gateway.security.XiaoWuSecurityContextRepository;
import pri.damai.xiaowu.gateway.security.core.XiaoWuAuthorizationManager;
import pri.damai.xiaowu.gateway.security.handle.XiaoWuAccessDeniedHandler;
import pri.damai.xiaowu.gateway.security.handle.XiaoWuAuthenticationEntryPoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * security 核心配置类
 * @Desc 在此详细配置 security
 * @Author DaMai
 * @Date 2021/3/23 15:26
 * 但行好事，莫问前程。
 */
@EnableWebFluxSecurity
@Slf4j
public class HttpSecurityConfig {

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Resource
    XiaoWuSecurityProperties securityProperties;

    @Resource
    private XiaoWuSecurityContextRepository xiaoWuSecurityContextRepository;

    @Resource
    private XiaoWuAccessDeniedHandler myAccessDeniedHandler;

    @Resource
    private XiaoWuAuthenticationEntryPoint xiaoWuAuthenticationEntryPoint;

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) {

        httpSecurity
                .csrf().disable()
                .httpBasic().disable()
                .formLogin().disable()
                .securityContextRepository(xiaoWuSecurityContextRepository)
                .authorizeExchange(exchange -> {
                    List<String> urlList = securityProperties.getNotLoginUrls();
                    String[] pattern = urlList.toArray(new String[0]);
                    log.info("securityWebFilterChain ignoreUrls:" + Arrays.toString(pattern));
                    // 过滤不需要拦截的url
                    exchange
                            .pathMatchers(pattern)
                            .permitAll()
                            // 拦截认证
                            .pathMatchers(HttpMethod.OPTIONS)
                            .permitAll()
                            .anyExchange()
                            .access(new XiaoWuAuthorizationManager(redisTemplate,securityProperties));
                })
                .exceptionHandling()
                .accessDeniedHandler(myAccessDeniedHandler)
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(xiaoWuAuthenticationEntryPoint)
                .and()
                .cors();
        ;
        return httpSecurity.build();
    }

}
